LwIP在逻辑上分为4个层次:链路层、网络层、传输层、应用层
LwIP协议栈内部使用了一个名为netif的网络接口结构来描述各种网络设备
LwIP为每个接口分配一个netif结构,用这个结构来描述每种接口的特性,如接口IP地址、接口状态等,同时在该结构中为每个接口注册对应的操作函数,如数据包输入函数、输出函数等。内核将所有网络接口的netif结构组织在一个叫做netif_list的链表上,当有IP数据包需要发送时,IP层会根据数据包的目的IP地址,在netif_list链表中选择一个最合适的网络接口,并调用其注册的数据包发送函数将数据包发送出去;当网卡接收到数据包时,其注册的数据包输入函数也会被调用,完成将数据包交给IP层的任务。
数据结构
netif.h
1234567891011121314151617181920212223242526272829303132// 下面几个宏为网络接口属性、状态相关的宏,主要用于描述netif中flags字段的各位struct netif {struct netif* next; //指向下一个netif结构,在构成链表netif_list时使用struct ip_addr ip_addr; //网络接口的IP地址struct ip_addr netmask; //子网掩码struct ip_addr gw; //网关地址err_t (*input)(strcut pbuf* p, strut netif* inp); //该函数向IP层输入数据包err_t (*output)(struct netif* netif, struct pbuf* p, struct ip_addr* ipaddr); // 该函数发送IP包err_t (*linkoutput)(struct netif* netif, struct pbuf* p); // 该函数实现底层数据包发送void* state; //该字段用户可以自由设置,例如用于指向一些底层设备相关的信息u16_t mtu; //该接口允许的最大数据包长度u8_t hwaddr_len; //该接口物理地址长度u8_t hwaddr[NETIF_MAX_HWARRR_LEN]; //该接口的物理地址u8_t flags; //该接口的状态、属性字段char name[2]; //该接口的名字u8_t num; //接口的编号//在接口自输入使能或者有环回接口的情况下,下面的字段用于描述接口发送给自己的数据包struct pbuf* loop_first; //指向发送给自己的数据包的第一个pbufstruct pbuf* loop_last; //指向发送给自己的数据包的最后一个pbuf};